import { View, Text } from "@tarojs/components";
import { AbstractImage, AbstractNavigator } from "@/components";
import style from "./index.module.scss";
import {
  PolygonBaseShape,
  DYNAMIC_EL_LAYOUT,
  STATIC_EL_LAYOUT,
  BACKGROUND_EL_LAYOUT,
  DynamicTileMenuKeys,
  StaticTileMenuKeys,
  BACKGROUND_COLORS,
} from "./tileMenuData";
import { useApplicationInfo } from "@/store/applicationDataContext";
import { useEffect, useMemo, useState } from "react";
import { clamp } from "@/utils/math";
import {
  CollagePayloadShape,
  DynamicStaticCollegeType,
} from "@/data/home/homeTypes";
import { usePageDimensions } from "@/hooks/usePageDimensions";
import { getDiscoverTabId } from "@/utils/navigation";
import { createIntersectionObserver } from "@tarojs/taro";
import { ActionKeys, ActionNames, sendAction } from "@/utils/tracking";

interface TileMenuProps {
  tileMenuItems: CollagePayloadShape;
  scrollOffsetRaw: number;
}

// In either pos/neg direction
const PARALLAX_MAX_FRAC = 0.05;

const DESIGN_HEIGHT_PX = 1619;

const C02TileMenu = ({ tileMenuItems, scrollOffsetRaw }: TileMenuProps) => {
  const { dispatch } = useApplicationInfo();

  const { heightExclNavbar, screenWidth } = usePageDimensions();
  const scrollOffset = scrollOffsetRaw - heightExclNavbar;

  const screenMultiplier = screenWidth / 375;

  const calcPolygonStyling = (
    inputData: PolygonBaseShape
  ): React.CSSProperties => {
    return {
      position: "absolute",
      top: inputData.top * screenMultiplier,
      width: inputData.width * screenMultiplier,
      height: inputData.height * screenMultiplier,
      left: inputData.left * screenMultiplier,
      clipPath: `polygon(${inputData.polygon
        .map((polygonCoords) => {
          return `${((polygonCoords.x - inputData.left) / inputData.width) * 100
            }% ${((polygonCoords.y - inputData.top) / inputData.height) * 100}%`;
        })
        .join(",")})`,
    };
  };

  const staticDynamicLookupElement = useMemo(() => {
    const returnObj: {
      [key in
      | StaticTileMenuKeys
      | DynamicTileMenuKeys]?: DynamicStaticCollegeType;
    } = {};
    tileMenuItems.forEach((dynamicOrStaticEl) => {
      returnObj[dynamicOrStaticEl.layoutArea] = dynamicOrStaticEl;
    });
    return returnObj;
  }, [tileMenuItems]);

  const combinedDynamicData = useMemo(() => {
    const combinedObject = {};
    for (const key in DYNAMIC_EL_LAYOUT) {
      const keyCast = key as DynamicTileMenuKeys;
      combinedObject[key] = {
        ...DYNAMIC_EL_LAYOUT[keyCast],
        ...staticDynamicLookupElement[keyCast],
      };
    }
    return combinedObject as {
      [key in DynamicTileMenuKeys]: PolygonBaseShape & DynamicStaticCollegeType;
    };
  }, [staticDynamicLookupElement]);

  const [activeText, setActiveText] = useState(new Set<string>());

  useEffect(() => {
    setTimeout(() => {
      if (combinedDynamicData) {
        Object.keys(combinedDynamicData).forEach((key) => {
          // @ts-ignore
          createIntersectionObserver()
            .relativeToViewport({ bottom: 100 })
            .observe(`.clickable-text-${key}`, (_) => {
              setActiveText((activeText) => new Set(activeText).add(key));
            });
        });
      }
    }, 200);
  }, [combinedDynamicData]);

  return (
    <View
      className={style["tile-menu-wrapper"]}
      style={{
        position: "relative",
        width: "100%",
        height: DESIGN_HEIGHT_PX * screenMultiplier,
        overflow: "hidden",
        // Just to hide possible minor gaps
        backgroundColor: "#bbb",
      }}
    >
      <>
        {/* Background sections */}
        {Object.entries(BACKGROUND_EL_LAYOUT).map(
          ([backgroundLayoutKey, backgroundLayoutData]) => {
            return (
              <View
                key={backgroundLayoutKey}
                style={
                  backgroundLayoutData.isCut
                    ? calcPolygonStyling(backgroundLayoutData)
                    : {
                      position: "absolute",
                      top: backgroundLayoutData.top * screenMultiplier,
                      width: backgroundLayoutData.width * screenMultiplier,
                      height: backgroundLayoutData.height * screenMultiplier,
                      left: backgroundLayoutData.left * screenMultiplier,
                    }
                }
              >
                <View
                  style={{
                    position: "absolute",
                    backgroundColor: BACKGROUND_COLORS[backgroundLayoutKey],
                    width: "100%",
                    height: "100%",
                  }}
                />
              </View>
            );
          }
        )}

        {/* Static sections */}
        {Object.entries(STATIC_EL_LAYOUT).map(
          ([staticLayoutKey, staticLayoutData]) => {
            const staticLayoutKeyCast = staticLayoutKey as StaticTileMenuKeys;
            return (
              <View
                key={staticLayoutKey}
                className={`${style.static}`}
                style={calcPolygonStyling(staticLayoutData)}
              >
                <AbstractImage
                  type="none"
                  src={
                    staticDynamicLookupElement[staticLayoutKeyCast]
                      ?.foreground ?? ""
                  }
                  style={{
                    position: "absolute",
                    top: "-2%",
                    left: "-2%",
                    width: "104%",
                    height: "104%",
                  }}
                />
              </View>
            );
          }
        )}

        {/* Dynamic sections */}
        {Object.entries(combinedDynamicData).map(
          ([dynLayoutKey, dynlayoutdata]) => (
            <View
              key={dynLayoutKey}
              className={`${style.dynamic}`}
              style={calcPolygonStyling(dynlayoutdata)}
            >
              <View
                style={{
                  position: "relative",
                  width: "100%",
                  height: "100%",
                }}
              >
                {/* Possible backgrounds */}
                {dynlayoutdata.backColor && (
                  <View
                    style={{
                      position: "absolute",
                      backgroundColor: dynlayoutdata.backColor,
                      width: "100%",
                      height: "100%",
                    }}
                  />
                )}
                {dynlayoutdata.background && (
                  <AbstractImage
                    type="none"
                    src={dynlayoutdata.background}
                    style={{
                      position: "absolute",
                      width: "100%",
                      height: "100%",
                    }}
                  />
                )}
                {/* Text and indicator behind layers */}
                <View
                  className={style["label-area-wrapper"]}
                  style={{
                    position: "absolute",
                    left: +dynlayoutdata.x! * screenMultiplier,
                    top: +dynlayoutdata.y! * screenMultiplier,
                    pointerEvents: "none",
                  }}
                >
                  <View
                    className={`${style["label-area"]}
                    ${
                      // Special treatment for cases where there is no background layers
                      !(dynlayoutdata.background || dynlayoutdata.backColor)
                        ? style["raised-z-index"]
                        : ""
                      }
                    `}
                  >
                    <View
                      className={`${style["clickable-text"]
                        } ${`clickable-text-${dynLayoutKey}`} ${activeText.has(dynLayoutKey) ? style["active"] : null
                        }`}
                    >
                      <Text>{dynlayoutdata.txt!}</Text>
                    </View>
                    <View
                      className={`
                        ${style["clickable-indicator"]}
                        ${dynlayoutdata.dotAfter === "true"
                          ? style["clickable-indicator-after"]
                          : style["clickable-indicator-before"]
                        }
                      `}
                    />
                  </View>
                </View>

                {/* Foreground always present */}
                <AbstractImage
                  className={`
                    ${style["foreground-image"]}
                    ${!(dynlayoutdata.background || dynlayoutdata.backColor)
                      ? style["full-dimensions"]
                      : ""
                    }
                    `}
                  type="none"
                  src={dynlayoutdata.foreground}
                  style={{
                    transform: `translateY(${clamp(
                      -(
                        scrollOffset +
                        heightExclNavbar / 2 -
                        (dynlayoutdata.top + dynlayoutdata.height / 2)
                      ) * 0.05,
                      -dynlayoutdata.height * PARALLAX_MAX_FRAC,
                      dynlayoutdata.height * PARALLAX_MAX_FRAC
                    )}px)`,
                    transition: "transform 0.1s linear",
                  }}
                />

                {/* Fake clickable areas (split from button areas) */}
                <AbstractNavigator
                  openType="switchTab"
                  onClick={() => {
                    sendAction(ActionNames.HomeModuleColumnClick, {
                      [ActionKeys.HomeModuleColumnButtonName]: dynlayoutdata.txt!,
                    });
                    if (
                      dynlayoutdata.target &&
                      dynlayoutdata.target !== "shop"
                    ) {
                      dispatch({
                        type: "DISCOVER_TAB",
                        data: {
                          tab: getDiscoverTabId(dynlayoutdata.target),
                        },
                      });
                    }
                  }}
                  url={
                    dynlayoutdata.target === "shop"
                      ? `pages/${dynlayoutdata.target}/index`
                      : `pages/discover/index`
                  }
                >
                  <View
                    style={{
                      position: "absolute",
                      width: 280 * screenMultiplier,
                      height: 100 * screenMultiplier,
                      left: (+dynlayoutdata.x! - 80) * screenMultiplier,
                      top: (+dynlayoutdata.y! - 15) * screenMultiplier,
                    }}
                  />
                </AbstractNavigator>
              </View>
            </View>
          )
        )}
      </>
    </View>
  );
};

export default C02TileMenu;
